/*
 * FSBlock.cpp
 *
 * Created on February 4, 2005, 8:36 AM
 * Modified:
 *      CGP; 1/25/09; Converted to C++
 */

#include "FSBlock.h"
#include "BlockException.h"
#include "Disk.h"
#include "IntArray.h"
#include <stdio.h>

void FSBlock::ConstructorInit(int length, int blockNumber) {
    m_buffer = new unsigned char[length];
    m_blockNumber = blockNumber;
    m_length = length;
    ClearBuffer();
}

bool FSBlock::GetDebug() {
    return m_BlockDebugFlag;
}

void FSBlock::Debug(bool state) {
    m_BlockDebugFlag = state;
}


FSBlock::FSBlock(int blockNumber, int length) {
    ConstructorInit(length, blockNumber);
}


FSBlock::~FSBlock() {
    // WARNING DO NOT UNCOMMENT
    //delete [] m_buffer;
}


FSBlock::FSBlock(int length) {
    ConstructorInit(length, 0);
}


void FSBlock::ClearBuffer() {
    for (unsigned int i=0; i < m_length; i++) {
        m_buffer[i] = 0;
    }
}


unsigned int FSBlock::GetBlockNumber() {
    return m_blockNumber;
}


void FSBlock::SetBlockNumber(unsigned int number) {
    m_blockNumber = number;
}


FSBlock::FSBlock(unsigned int blockNumber, Disk *disk) {
    ConstructorInit(disk->blockSize(), blockNumber);
    
    //printf("Here1"); System.out.flush();

    if (((int) blockNumber < 0) || (blockNumber >= disk->numberOfBlocks())) {
        if (m_BlockDebugFlag) 
            printf("FSBlock.FSBlock: ERROR: Bad block number= %d\n", blockNumber);
        throw BlockException();
    }

    if (m_buffer == NULL) {
        printf("FSBlock.FSBlock: ERROR: NULL m_buffer!\n");
        throw BlockException();
    }

    m_blockNumber = blockNumber;

    // Need to read the block and initialize the nextPointer of the FSBlock

    //printf("Here1.1"); System.out.flush();

    if (! disk->ReadBlock(blockNumber, m_buffer)) {
        printf("FSBlock.FSBlock: ERROR: Cannot read from Disk; block number= %d\n", blockNumber);
        throw BlockException();
    }
}


bool FSBlock::Write(Disk *disk) {
    //printf("FSBlock.Write: block number= " + GetBlockNumber());
    //printf("FSBlock.Write: next pointer= " + GetNextPointer());
    //printf("FSBlock.Write: second pointer= " + GetSecondPointer());

    if (((int) m_blockNumber < 0) || (m_blockNumber >= disk->numberOfBlocks())) {
        printf("FSBlock.Write: ERROR: Bad block number= %d\n", m_blockNumber);
        return false;
    }

    // Write the block to the file
    if (! disk->WriteBlock(m_blockNumber, m_buffer)) {
        printf("FSBlock.Write: ERROR: Cannot write block to disk\n");
        return false;
    }

    return true;
}


unsigned char *FSBlock::GetBuffer() {
    return m_buffer;
}


void FSBlock::SetBuffer(unsigned char *buffer) {
    delete [] m_buffer;
    m_buffer = buffer;
}


void FSBlock::SetInt(int pointer, int location) {
	IntArray::SetInt(m_buffer, pointer, location);
}


int FSBlock::GetInt(int location) {
    return IntArray::GetInt(m_buffer, location);
}


unsigned int FSBlock::GetBlockSize() {
    return m_length;
}


void FSBlock::Print() {
  printf("  Block Number: %d\n", m_blockNumber);
  printf("  m_length:     %d\n", m_length);
  printf("  m_buffer:     %s\n", m_buffer);
}




